package de.jonasjelten.jcalc.gui;

import de.jonasjelten.jcalc.api.JCalc;
import de.jonasjelten.jcalc.api.JCalcInterface;
import de.jonasjelten.jcalc.easteregg.JEasterEgg;
import de.jonasjelten.jcalc.mathExps.JMathExp;
import de.jonasjelten.jcalc.exception.JCalcException;
import de.jonasjelten.jcalc.math.JThreadGroup;
import java.awt.event.*;
import javax.swing.*;

/**
 * Diese Klasse enthält das GUI der jCalc
 * Sie wird zum setzten von Statusinformationen auch an JMathExpressions weitergegeben.
 * 
 * @author michael, fabian, jonas
 */
public class MainWindow extends JFrame implements JCalcInterface {

    
    boolean calculationinprogress = false;
    String lastentered = "";
    FileChooserWindow fcwind;
    JThreadGroup calcthreads;
    boolean eastereggmode = false;
    JEasterEgg easteregg;
    JCalc jcalc = new JCalc(this);

    /** Creates new form mainWindow */
    public MainWindow() {
        try {
            String laf = UIManager.getSystemLookAndFeelClassName();
            UIManager.setLookAndFeel(laf);
        } catch (Exception exc) {
            System.err.println(exc.toString());
            try {
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
            } catch (Exception exz) {
                System.err.println(exz.toString());
            }
        }
        initComponents();
        setLocationRelativeTo(null);
        fcwind = new FileChooserWindow(this);
        Runnable wavinmethod = new Runnable() {

            @Override
            public void run() {
                while (true) {
                    double yourgun = (Math.sin(System.currentTimeMillis() / 2000.0) + 1) * 50; // lol @ serious quote...

                    freezeMonitor.setValue((int) yourgun);
                    freezePercent.setText((int) yourgun + " %");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException ex) {
                        System.out.println(ex);
                    }
                }
            }
        };
        Thread wavinthread = new Thread(wavinmethod, "Statusbarthread");
        wavinthread.setPriority(4);
        wavinthread.start();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        AboutWindow = new javax.swing.JDialog();
        AboutWindowPanel = new javax.swing.JPanel();
        AboutTextLabel = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        SettingsDialog = new javax.swing.JDialog();
        TabPane = new javax.swing.JTabbedPane();
        ThreadSettingsPanel = new javax.swing.JPanel();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jTextField2 = new javax.swing.JTextField();
        PrecisionSettingsPanel = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jTextField1 = new javax.swing.JTextField();
        jCheckBox1 = new javax.swing.JCheckBox();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        mathExpInputField = new javax.swing.JTextField();
        mathExpInputFieldLabel = new javax.swing.JLabel();
        initEvalButton = new javax.swing.JButton();
        byLabel = new javax.swing.JLabel();
        ProgressResultSplitPane = new javax.swing.JSplitPane();
        ProgressPane = new javax.swing.JPanel();
        progressTextAreaContainer = new javax.swing.JScrollPane();
        progressTextArea = new javax.swing.JTextArea();
        progressFieldLabel = new javax.swing.JLabel();
        calcProgressLabel = new javax.swing.JLabel();
        calcProgressBar = new javax.swing.JProgressBar();
        ResultPane = new javax.swing.JPanel();
        resultFieldLabel = new javax.swing.JLabel();
        outputTextAreaContainer = new javax.swing.JScrollPane();
        outputTextArea = new javax.swing.JTextArea();
        freezeMonitor = new javax.swing.JProgressBar();
        jLabel1 = new javax.swing.JLabel();
        freezePercent = new javax.swing.JLabel();
        digitcount = new javax.swing.JLabel();
        digitlabel = new javax.swing.JLabel();
        ClearInputButton = new javax.swing.JButton();
        MainMenuBar = new javax.swing.JMenuBar();
        FunctionsMenu = new javax.swing.JMenu();
        SaveCalcItem = new javax.swing.JMenuItem();
        SettingsMenuItem = new javax.swing.JMenuItem();
        FunctionsMenuSeparator = new javax.swing.JPopupMenu.Separator();
        ExitItem = new javax.swing.JMenuItem();
        InfoMenu = new javax.swing.JMenu();
        AboutItem = new javax.swing.JMenuItem();

        AboutWindow.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        AboutWindow.setTitle("About jCalc");
        AboutWindow.setBounds(new java.awt.Rectangle(0, 0, 0, 0));
        AboutWindow.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        AboutWindow.setMinimumSize(new java.awt.Dimension(300, 150));
        AboutWindow.setModal(true);
        AboutWindow.setName("AboutWindow"); // NOI18N
        AboutWindow.setResizable(false);
        AboutWindow.setUndecorated(true);
        AboutWindow.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                DisposeAboutWindow(evt);
            }
        });

        AboutWindowPanel.setBackground(new java.awt.Color(0, 0, 0));
        AboutWindowPanel.setPreferredSize(new java.awt.Dimension(300, 150));
        AboutWindowPanel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                DisposeAboutWindow(evt);
            }
        });

        AboutTextLabel.setFont(new java.awt.Font("Tahoma", 0, 18));
        AboutTextLabel.setForeground(new java.awt.Color(255, 255, 255));
        AboutTextLabel.setText("© 2010");

        jLabel2.setFont(new java.awt.Font("Tahoma", 0, 14));
        jLabel2.setForeground(new java.awt.Color(255, 255, 255));
        jLabel2.setText("TheJJ, mic-e, pc-master, kernphysiker235");

        jLabel3.setFont(new java.awt.Font("Tahoma", 1, 36));
        jLabel3.setForeground(new java.awt.Color(255, 255, 255));
        jLabel3.setText("jCalc");

        javax.swing.GroupLayout AboutWindowPanelLayout = new javax.swing.GroupLayout(AboutWindowPanel);
        AboutWindowPanel.setLayout(AboutWindowPanelLayout);
        AboutWindowPanelLayout.setHorizontalGroup(
            AboutWindowPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(AboutWindowPanelLayout.createSequentialGroup()
                .addGap(20, 20, 20)
                .addComponent(jLabel2)
                .addContainerGap(24, Short.MAX_VALUE))
            .addGroup(AboutWindowPanelLayout.createSequentialGroup()
                .addGap(105, 105, 105)
                .addGroup(AboutWindowPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(AboutWindowPanelLayout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(AboutTextLabel))
                    .addComponent(jLabel3))
                .addContainerGap(106, Short.MAX_VALUE))
        );
        AboutWindowPanelLayout.setVerticalGroup(
            AboutWindowPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, AboutWindowPanelLayout.createSequentialGroup()
                .addGap(34, 34, 34)
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(AboutTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 35, Short.MAX_VALUE)
                .addGap(1, 1, 1)
                .addComponent(jLabel2)
                .addContainerGap())
        );

        javax.swing.GroupLayout AboutWindowLayout = new javax.swing.GroupLayout(AboutWindow.getContentPane());
        AboutWindow.getContentPane().setLayout(AboutWindowLayout);
        AboutWindowLayout.setHorizontalGroup(
            AboutWindowLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(AboutWindowPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        AboutWindowLayout.setVerticalGroup(
            AboutWindowLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(AboutWindowPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 153, Short.MAX_VALUE)
        );

        SettingsDialog.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        SettingsDialog.setTitle("jCalc Settings");
        SettingsDialog.setAlwaysOnTop(true);

        jLabel6.setText("Fakultätberechnung");

        jLabel7.setText("Threadanzahl:");

        jTextField2.setText("4");

        javax.swing.GroupLayout ThreadSettingsPanelLayout = new javax.swing.GroupLayout(ThreadSettingsPanel);
        ThreadSettingsPanel.setLayout(ThreadSettingsPanelLayout);
        ThreadSettingsPanelLayout.setHorizontalGroup(
            ThreadSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ThreadSettingsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ThreadSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(ThreadSettingsPanelLayout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(jLabel7)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jLabel6))
                .addContainerGap(256, Short.MAX_VALUE))
        );
        ThreadSettingsPanelLayout.setVerticalGroup(
            ThreadSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ThreadSettingsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel6)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(ThreadSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel7)
                    .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(357, Short.MAX_VALUE))
        );

        TabPane.addTab("Thread Settings", ThreadSettingsPanel);

        jLabel4.setText("Stellenanzahl");

        jLabel5.setText("Max. signifikante Stellen:");

        jTextField1.setText("100");
        jTextField1.setInputVerifier(new JOnlyNumbersPosInt());
        jTextField1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField1ActionPerformed(evt);
            }
        });

        jCheckBox1.setText("Vorkommastellen nie runden");

        javax.swing.GroupLayout PrecisionSettingsPanelLayout = new javax.swing.GroupLayout(PrecisionSettingsPanel);
        PrecisionSettingsPanel.setLayout(PrecisionSettingsPanelLayout);
        PrecisionSettingsPanelLayout.setHorizontalGroup(
            PrecisionSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(PrecisionSettingsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(PrecisionSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel4)
                    .addGroup(PrecisionSettingsPanelLayout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(jLabel5)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jCheckBox1)))
                .addContainerGap(33, Short.MAX_VALUE))
        );
        PrecisionSettingsPanelLayout.setVerticalGroup(
            PrecisionSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(PrecisionSettingsPanelLayout.createSequentialGroup()
                .addGap(22, 22, 22)
                .addComponent(jLabel4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(PrecisionSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jCheckBox1))
                .addContainerGap(344, Short.MAX_VALUE))
        );

        TabPane.addTab("Precision Settings", PrecisionSettingsPanel);

        jButton1.setText("Apply");
        jButton1.setEnabled(false);
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setText("Cancel");

        jButton3.setText("OK");

        javax.swing.GroupLayout SettingsDialogLayout = new javax.swing.GroupLayout(SettingsDialog.getContentPane());
        SettingsDialog.getContentPane().setLayout(SettingsDialogLayout);
        SettingsDialogLayout.setHorizontalGroup(
            SettingsDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, SettingsDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(SettingsDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(SettingsDialogLayout.createSequentialGroup()
                        .addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 72, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(TabPane, javax.swing.GroupLayout.DEFAULT_SIZE, 427, Short.MAX_VALUE))
                .addContainerGap())
        );
        SettingsDialogLayout.setVerticalGroup(
            SettingsDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(SettingsDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(TabPane, javax.swing.GroupLayout.PREFERRED_SIZE, 433, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 13, Short.MAX_VALUE)
                .addGroup(SettingsDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jButton2)
                    .addComponent(jButton3))
                .addContainerGap())
        );

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("jCalc");
        setMinimumSize(new java.awt.Dimension(400, 300));

        mathExpInputField.setToolTipText("Enter mathematical expression to be evaluated on ENTER");
        mathExpInputField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                mathExpInputFieldKeyPressed(evt);
            }
        });

        mathExpInputFieldLabel.setText("Enter mathematical expression:");

        initEvalButton.setText("Evaluate");
        initEvalButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                initEvalButtonMouseClicked(evt);
            }
        });
        initEvalButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                initEvalButtonActionPerformed(evt);
            }
        });

        byLabel.setText("(c) by JJ, mic-e & pc-master");

        ProgressResultSplitPane.setBorder(null);
        ProgressResultSplitPane.setDividerLocation(175);
        ProgressResultSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        ProgressResultSplitPane.setContinuousLayout(true);
        ProgressResultSplitPane.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

        progressTextArea.setColumns(20);
        progressTextArea.setEditable(false);
        progressTextArea.setRows(5);
        progressTextArea.setCursor(new java.awt.Cursor(java.awt.Cursor.TEXT_CURSOR));
        progressTextAreaContainer.setViewportView(progressTextArea);

        progressFieldLabel.setText("Progress output window:");

        calcProgressLabel.setFont(new java.awt.Font("Tahoma", 1, 11));
        calcProgressLabel.setText("0 %");

        javax.swing.GroupLayout ProgressPaneLayout = new javax.swing.GroupLayout(ProgressPane);
        ProgressPane.setLayout(ProgressPaneLayout);
        ProgressPaneLayout.setHorizontalGroup(
            ProgressPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ProgressPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ProgressPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(progressTextAreaContainer, javax.swing.GroupLayout.DEFAULT_SIZE, 1075, Short.MAX_VALUE)
                    .addGroup(ProgressPaneLayout.createSequentialGroup()
                        .addComponent(progressFieldLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(calcProgressLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(calcProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 905, Short.MAX_VALUE)))
                .addContainerGap())
        );
        ProgressPaneLayout.setVerticalGroup(
            ProgressPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, ProgressPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ProgressPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(ProgressPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(progressFieldLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(calcProgressLabel))
                    .addComponent(calcProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(progressTextAreaContainer, javax.swing.GroupLayout.DEFAULT_SIZE, 144, Short.MAX_VALUE))
        );

        ProgressResultSplitPane.setLeftComponent(ProgressPane);

        resultFieldLabel.setText("Final result:");

        outputTextArea.setColumns(20);
        outputTextArea.setEditable(false);
        outputTextArea.setLineWrap(true);
        outputTextArea.setRows(3);
        outputTextArea.setCursor(new java.awt.Cursor(java.awt.Cursor.TEXT_CURSOR));
        outputTextAreaContainer.setViewportView(outputTextArea);

        jLabel1.setText("Installing Windows... please wait!");

        freezePercent.setFont(new java.awt.Font("Tahoma", 1, 11));
        freezePercent.setText("0 %");

        digitcount.setText("0");

        digitlabel.setText("Digits:");

        javax.swing.GroupLayout ResultPaneLayout = new javax.swing.GroupLayout(ResultPane);
        ResultPane.setLayout(ResultPaneLayout);
        ResultPaneLayout.setHorizontalGroup(
            ResultPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, ResultPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ResultPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(outputTextAreaContainer, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 1075, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, ResultPaneLayout.createSequentialGroup()
                        .addComponent(resultFieldLabel)
                        .addGap(96, 96, 96)
                        .addComponent(digitlabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(digitcount, javax.swing.GroupLayout.PREFERRED_SIZE, 199, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(freezeMonitor, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 1075, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, ResultPaneLayout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(freezePercent)))
                .addContainerGap())
        );
        ResultPaneLayout.setVerticalGroup(
            ResultPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ResultPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ResultPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(resultFieldLabel)
                    .addComponent(digitcount)
                    .addComponent(digitlabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(outputTextAreaContainer, javax.swing.GroupLayout.DEFAULT_SIZE, 75, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(ResultPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(freezePercent))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(freezeMonitor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        ProgressResultSplitPane.setRightComponent(ResultPane);

        ClearInputButton.setText("Clear");
        ClearInputButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ClearInputButton.setIconTextGap(0);
        ClearInputButton.setMargin(new java.awt.Insets(2, 2, 2, 0));
        ClearInputButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ClearInputButtonActionPerformed(evt);
            }
        });

        FunctionsMenu.setText("Tasks");
        FunctionsMenu.setToolTipText("");

        SaveCalcItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        SaveCalcItem.setText("Save calculation as txt");
        SaveCalcItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SaveAsTxt(evt);
            }
        });
        FunctionsMenu.add(SaveCalcItem);

        SettingsMenuItem.setText("Settings");
        SettingsMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SettingsMenuItemActionPerformed(evt);
            }
        });
        FunctionsMenu.add(SettingsMenuItem);
        FunctionsMenu.add(FunctionsMenuSeparator);

        ExitItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.CTRL_MASK));
        ExitItem.setText("Exit jCalc");
        ExitItem.setActionCommand("exit");
        ExitItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ExitItemActionPerformed(evt);
            }
        });
        FunctionsMenu.add(ExitItem);

        MainMenuBar.add(FunctionsMenu);

        InfoMenu.setText("Info");

        AboutItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, java.awt.event.InputEvent.CTRL_MASK));
        AboutItem.setText("About jCalc");
        AboutItem.setToolTipText("Show an info dialog about jCalc.");
        AboutItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AboutItemActionPerformed(evt);
            }
        });
        InfoMenu.add(AboutItem);

        MainMenuBar.add(InfoMenu);

        setJMenuBar(MainMenuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(mathExpInputField, javax.swing.GroupLayout.DEFAULT_SIZE, 910, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(ClearInputButton, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(initEvalButton, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(mathExpInputFieldLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 790, Short.MAX_VALUE)
                        .addComponent(byLabel)))
                .addContainerGap())
            .addComponent(ProgressResultSplitPane, javax.swing.GroupLayout.Alignment.TRAILING)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(mathExpInputFieldLabel)
                    .addComponent(byLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(mathExpInputField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(initEvalButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(ClearInputButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(ProgressResultSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 342, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void initEvalButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_initEvalButtonActionPerformed
        mathExpInputField.requestFocus();
        if (!calculationinprogress) {
            calculationinprogress = true;
            evaluateInputString();
        }
    }//GEN-LAST:event_initEvalButtonActionPerformed

    private void mathExpInputFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_mathExpInputFieldKeyPressed
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            if (!calculationinprogress) {
                calculationinprogress = true;
                evaluateInputString();
            }
        }
    }//GEN-LAST:event_mathExpInputFieldKeyPressed

    private void initEvalButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_initEvalButtonMouseClicked
        //mathExpInputField.requestFocus();
        //evaluateInputString();
    }//GEN-LAST:event_initEvalButtonMouseClicked

    private void ExitItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ExitItemActionPerformed
        //TODO: evtl ueberpruefen ob man bereit is zum beenden des kriegs
        System.exit(0);
    }//GEN-LAST:event_ExitItemActionPerformed

    private void AboutItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AboutItemActionPerformed
        AboutWindow.setLocationRelativeTo(null);
        AboutWindow.setVisible(true);
    }//GEN-LAST:event_AboutItemActionPerformed

    private void SaveAsTxt(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SaveAsTxt
        if (!progressTextArea.getText().equals("")) {
            fcwind.setLocationRelativeTo(this);
            fcwind.setVisible(true);
        }
    }//GEN-LAST:event_SaveAsTxt

    private void DisposeAboutWindow(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_DisposeAboutWindow
        AboutWindow.dispose();
    }//GEN-LAST:event_DisposeAboutWindow

    private void ClearInputButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ClearInputButtonActionPerformed
        mathExpInputField.setText(null);
        mathExpInputField.requestFocus();
    }//GEN-LAST:event_ClearInputButtonActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField1ActionPerformed
    }//GEN-LAST:event_jTextField1ActionPerformed

    private void SettingsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SettingsMenuItemActionPerformed
        // TODO add your handling code here:
        SettingsDialog.setLocationRelativeTo(null);
        SettingsDialog.setVisible(true);
    }//GEN-LAST:event_SettingsMenuItemActionPerformed

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new MainWindow().setVisible(true);
            }
        });
    }
    // <editor-fold defaultstate="collapsed" desc="variables declaration">
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem AboutItem;
    private javax.swing.JLabel AboutTextLabel;
    private javax.swing.JDialog AboutWindow;
    private javax.swing.JPanel AboutWindowPanel;
    private javax.swing.JButton ClearInputButton;
    private javax.swing.JMenuItem ExitItem;
    private javax.swing.JMenu FunctionsMenu;
    private javax.swing.JPopupMenu.Separator FunctionsMenuSeparator;
    private javax.swing.JMenu InfoMenu;
    private javax.swing.JMenuBar MainMenuBar;
    private javax.swing.JPanel PrecisionSettingsPanel;
    private javax.swing.JPanel ProgressPane;
    private javax.swing.JSplitPane ProgressResultSplitPane;
    private javax.swing.JPanel ResultPane;
    private javax.swing.JMenuItem SaveCalcItem;
    private javax.swing.JDialog SettingsDialog;
    private javax.swing.JMenuItem SettingsMenuItem;
    private javax.swing.JTabbedPane TabPane;
    private javax.swing.JPanel ThreadSettingsPanel;
    private javax.swing.JLabel byLabel;
    private javax.swing.JProgressBar calcProgressBar;
    private javax.swing.JLabel calcProgressLabel;
    private javax.swing.JLabel digitcount;
    private javax.swing.JLabel digitlabel;
    private javax.swing.JProgressBar freezeMonitor;
    private javax.swing.JLabel freezePercent;
    private javax.swing.JButton initEvalButton;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;
    private javax.swing.JTextField mathExpInputField;
    private javax.swing.JLabel mathExpInputFieldLabel;
    private javax.swing.JTextArea outputTextArea;
    private javax.swing.JScrollPane outputTextAreaContainer;
    private javax.swing.JLabel progressFieldLabel;
    private javax.swing.JTextArea progressTextArea;
    private javax.swing.JScrollPane progressTextAreaContainer;
    private javax.swing.JLabel resultFieldLabel;
    // End of variables declaration//GEN-END:variables
    // </editor-fold>

    /**
     * @autor fabian
     *
     * Those methods are there for setting the progress percent & echoing text
     * in the progress window/final result window
     */
    private void setProgressPercent(int x) {
        calcProgressBar.setValue(x);
        calcProgressLabel.setText(x + " %");
    }

    public synchronized void echoProgress(String text) {
        if (text != null) {
            System.out.println(text);
            progressTextArea.append(text + "\r\n");
            progressTextArea.setCaretPosition(progressTextArea.getText().length()); //TODO: sometimes deadlocks with the AWT-EventQueue-0 Thread cause of waitin for repaint maybe
        }
    }

    public void setFinalResult(String result) {
        outputTextArea.setText(result);
    }

    /**
     * Erzeugt den Text für die Dateispeicherung
     * @return Ausgabetext für Textdatei
     */
    public String ReturnSummarizedCalc() {
        return "jCalc calculation log\r\n\r\nEntered expression: " + mathExpInputField.getText() + "\r\n\r\nMathematical expression to solve:\r\n" + mathExpInputField.getText() + "\r\n\r\nCalculation Log:\r\n" + progressTextArea.getText() + "\r\n\r\nFinal result: (" + digitcount.getText() + " digits)\r\n" + outputTextArea.getText();
    }

    /**
     * this method is called by a finished mathexp
     * it sets output information and updates the statusbar
     * @param mathExpThatJustFinished our finished mathexpression
     */
    /*public void updateProgressOnMathExpFinished(JMathExp mathExpThatJustFinished, boolean isCached) { // maybe not synchronized because of new-thread-starting


    int abwievielkuerzen = JPreferences.abwievielkürzen;
    int aufwievielekuerzen = JPreferences.aufwievielekürzen;

    finishedNonTrivialMathExpsCount++;
    int progress = (100 * finishedNonTrivialMathExpsCount) / totalNonTrivialMathExpsCount;


    String mathExp = mathExpThatJustFinished.forceResult().toString();

    BigInteger strlen = BigInteger.valueOf((long) mathExp.length());
    String what;
    String howmuchleft = "";
    String evalue = "";
    // lets remove the minus
    if (strlen.compareTo(BigInteger.ZERO) < 0) {
    strlen.subtract(BigInteger.ONE);
    }
    if (strlen.compareTo(BigInteger.valueOf(abwievielkuerzen)) > 0) {
    what = mathExp.substring(0, aufwievielekuerzen);
    howmuchleft = ".... " + strlen.subtract(BigInteger.valueOf(aufwievielekuerzen)) + " more digits";
    } else {
    what = mathExp;
    }
    String iscache = isCached ? "Cached" : "Intermediate";
    synchronized (this) {
    if (progress == 100) {
    progress = 99;
    }
    //TODO: Dies hier ist dir funktionierende aktivthreadanzahl!
    //echoProgress("Threadzahl: " + calcthreads.activeCount());

    echoProgress(resultcount++ + ". " + iscache + " result of " + mathExpThatJustFinished.toString() + " (" + strlen + " digits): "
    + " = " + what + howmuchleft + evalue
    + "\r\n Calculation progress: " + progress + "% Threads: active:" + (calcthreads.runningThreads) + " running: " + (calcthreads.activeCount() - 1));
    setProgressPercent(progress);
    }
    }
     * 
     */
    /**
     * @autor michael, fabian, jonas
     *
     * This method is called when the user pressed enter in the input field or
     * manually pressed the "Evaluate" button.
     */
    public void evaluateInputString() {
        //progressTextArea wird beim Ausführen einer neuen Rechnung gecleart
        progressTextArea.setText(null);
        initEvalButton.setEnabled(false);
        initEvalButton.setText("Evaluating");
        outputTextArea.setText("your input is being evaluated by microsoft servers... please wait for most probably a very long time.");
        setProgressPercent(0);
        digitcount.setText("0");
        lastentered = mathExpInputField.getText();
        boolean canbereenabled = true;
        String inputString = lastentered.toLowerCase().trim().replaceAll("\\s", "");

        System.out.println("Evaluating input string: " + inputString);

        if (inputString.matches("^sudo.*")) {
            // init easteregg
            easteregg = new JEasterEgg(this);
            eastereggmode = true;
            easteregg.onEnter(inputString);
        } else if (eastereggmode) {
            easteregg.onEnter(inputString);
        } else if (inputString.matches("^exit$")) {
            //eastereggmode = false;
            System.exit(0);
        } else if (inputString.equals("")) {
            //nix tun halt...
        } else {
            JMathExp root;
            try {

                root = jcalc.parse(inputString);


                canbereenabled = false;
                evaluateMathExp(root);


            } catch (JCalcException ex) {
                echoProgress(ex.getMessage());
                System.out.println(ex + "\n");
                canbereenabled = true;
            } catch (Exception ex) {
                ex.printStackTrace(System.err);
                echoProgress("Error: " + ex.getMessage());
                System.out.println(ex + "\n");
                canbereenabled = true;
            }
        }
        if (canbereenabled) {
            resetAll(true, false);
        }
    }

    private void resetAll() {
        resetAll(false, false);
    }

    public void resetInput() {
        mathExpInputField.setText("");
    }

    public void resetAll(boolean resettexts, boolean resetprogress) {
        if (resettexts) {

            outputTextArea.setText("");
        }
        if (resetprogress) {
            progressTextArea.setText("");
        }
        calculationinprogress = false;
        initEvalButton.setEnabled(true);
        initEvalButton.setText("Evaluate");
    }

    private void evaluateMathExp(final JMathExp root) {
        jcalc.evalMathExp(root);
    }

    @Override
    public void finishedCalculating(String message) {
        echoProgress(message);
    }

    @Override
    public void intermediateResult(String message) {
        echoProgress(message);
    }

    @Override
    public void echo(String txt) {
        echoProgress(txt);
    }

    @Override
    public void setProgress(int progress) {
        setProgressPercent(progress);
    }

    @Override
    public void finalResult(String result) {

        int erglength = result.length();
        if (result.charAt(0) == '-') {
            erglength--;
        }
        digitcount.setText(erglength + "");
        outputTextArea.setText(result);
        resetAll();
    }

    @Override
    public void errorMessage(String message) {
        echoProgress("ErrorMSG: " + message);
    }

    class JOnlyNumbersPosInt extends javax.swing.InputVerifier {

        @Override
        public boolean verify(JComponent input) {
            JTextField tf = (JTextField) input;
            boolean isok = true;
            isok = tf.getText().matches("\\d{1,}");
            if (isok) {
                isok = Integer.parseInt(tf.getText()) <= Integer.MAX_VALUE;
            }
            return isok;
        }
    }

    class JOnlyNumbers extends javax.swing.InputVerifier {

        @Override
        public boolean verify(JComponent input) {
            JTextField tf = (JTextField) input;
            return tf.getText().matches("\\d{1,2}");
        }
    }
}
